#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "RingBuffer.h"

#define NUM_THREADS	4
#define RING_BUFFER_SIZE 65536

RingBuffer* ringbuffer;

void *BusyWork(void *t)
{
	int i;
	long tid;
	double result=0.0;
	tid = (long)t;
	fprintf(stderr, "Thread %ld starting...\n", tid);

	for (i=0; i<1024; i++)
		ringbuffer->Write((unsigned char *)i, 1);
	ringbuffer->ShowBuffer();

	fprintf(stderr, "Thread %ld done. Result = %e\n", tid, result);

	pthread_exit((void*) t);
}

int main (int argc, char *argv[])
{
	pthread_t thread[NUM_THREADS];
	pthread_attr_t attr;
	int rc;
	long t;
	void *status;

	// Create a 4 second ring data buffer
	ringbuffer = new RingBuffer(RING_BUFFER_SIZE);
	ringbuffer->Empty();

	// Initialize and set thread detached attribute
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

	for (t = 0; t < NUM_THREADS; t++)
	{
		fprintf(stderr, "Main: creating thread %ld\n", t);
		rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t);
		if (rc)
		{
			fprintf(stderr, "ERROR; return code from pthread_create() is %d\n", rc);
			exit(-1);
		}
	}

	// Free attribute and wait for the other threads
	pthread_attr_destroy(&attr);
	for (t = 0; t < NUM_THREADS; t++)
	{
		rc = pthread_join(thread[t], &status);
		if (rc)
		{
			fprintf(stderr, "ERROR; return code from pthread_join() is %d\n", rc);
			exit(-1);
		}

		fprintf(stderr, "Main: completed join with thread %ld having a status of %ld\n", t, (long)status);
	}

	fprintf(stderr, "Main: program completed. Exiting.\n");

	ringbuffer->ShowBuffer();

	pthread_exit(NULL);
}
